package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.category.request.CategoryBatchOperationRequest;
import com.blog.cmrpersonalblog.dto.category.request.CategoryCreateRequest;
import com.blog.cmrpersonalblog.dto.category.request.CategoryQueryRequest;
import com.blog.cmrpersonalblog.dto.category.request.CategoryUpdateRequest;
import com.blog.cmrpersonalblog.dto.category.response.CategoryManagementResponse;
import com.blog.cmrpersonalblog.entity.ArticleCategory;
import com.blog.cmrpersonalblog.service.CategoryManagementService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 分类管理控制器
 * 提供分类的管理功能，包括列表查询、创建、更新、删除、批量操作等
 */
@Slf4j
@RestController
@RequestMapping("/admin/categories")
@CrossOrigin(origins = "*", maxAge = 3600)
@SaCheckRole("admin")
@Validated
public class CategoryManagementController {

   @Resource
    private CategoryManagementService categoryManagementService;

    /**
     * 分页查询分类列表
     */
    @GetMapping("/list")
    public Result<IPage<CategoryManagementResponse>> getCategoryList(CategoryQueryRequest queryRequest) {
        log.info("管理员查询分类列表: {}", queryRequest);
        try {
            IPage<CategoryManagementResponse> pageResult = categoryManagementService.getCategoryList(queryRequest);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("查询分类列表失败", e);
            return Result.error("查询分类列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取分类详情
     */
    @GetMapping("/{categoryId}")
    public Result<CategoryManagementResponse> getCategoryDetail(@PathVariable @NotNull Long categoryId) {
        log.info("管理员查看分类详情: categoryId={}", categoryId);
        try {
            CategoryManagementResponse categoryDetail = categoryManagementService.getCategoryDetail(categoryId);
            if (categoryDetail == null) {
                return Result.error("分类不存在");
            }
            return Result.success(categoryDetail);
        } catch (Exception e) {
            log.error("获取分类详情失败", e);
            return Result.error("获取分类详情失败：" + e.getMessage());
        }
    }

    /**
     * 创建分类
     */
    @PostMapping("/create")
    public Result<Void> createCategory(@RequestBody @Valid CategoryCreateRequest createRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员创建分类: request={}, operatorId={}", createRequest, operatorId);
        
        try {
            boolean success = categoryManagementService.createCategory(createRequest, operatorId);
            if (success) {
                return Result.success("分类创建成功");
            } else {
                return Result.error("分类创建失败");
            }
        } catch (Exception e) {
            log.error("创建分类失败", e);
            return Result.error("创建分类失败：" + e.getMessage());
        }
    }

    /**
     * 更新分类
     */
    @PutMapping("/update")
    public Result<Void> updateCategory(@RequestBody @Valid CategoryUpdateRequest updateRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员更新分类: request={}, operatorId={}", updateRequest, operatorId);
        
        try {
            boolean success = categoryManagementService.updateCategory(updateRequest, operatorId);
            if (success) {
                return Result.success("分类更新成功");
            } else {
                return Result.error("分类更新失败");
            }
        } catch (Exception e) {
            log.error("更新分类失败", e);
            return Result.error("更新分类失败：" + e.getMessage());
        }
    }

    /**
     * 删除分类
     */
    @DeleteMapping("/{categoryId}")
    public Result<Void> deleteCategory(@PathVariable @NotNull Long categoryId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员删除分类: categoryId={}, operatorId={}", categoryId, operatorId);
        
        try {
            boolean success = categoryManagementService.deleteCategory(categoryId, operatorId);
            if (success) {
                return Result.success("分类删除成功");
            } else {
                return Result.error("分类删除失败");
            }
        } catch (Exception e) {
            log.error("删除分类失败", e);
            return Result.error("删除分类失败：" + e.getMessage());
        }
    }

    /**
     * 批量操作分类
     */
    @PostMapping("/batch")
    public Result<Map<String, Object>> batchOperateCategories(@RequestBody @Valid CategoryBatchOperationRequest batchRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员批量操作分类: request={}, operatorId={}", batchRequest, operatorId);
        
        try {
            Map<String, Object> result = categoryManagementService.batchOperateCategories(batchRequest, operatorId);
            if ((Boolean) result.get("success")) {
                return Result.success("批量操作成功", result);
            } else {
                return Result.error("批量操作失败：" + result.get("error"));
            }
        } catch (Exception e) {
            log.error("批量操作分类失败", e);
            return Result.error("批量操作失败：" + e.getMessage());
        }
    }

    /**
     * 启用分类
     */
    @PostMapping("/{categoryId}/enable")
    public Result<Void> enableCategory(@PathVariable @NotNull Long categoryId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员启用分类: categoryId={}, operatorId={}", categoryId, operatorId);
        
        try {
            boolean success = categoryManagementService.enableCategory(categoryId, operatorId);
            if (success) {
                return Result.success("分类启用成功");
            } else {
                return Result.error("分类启用失败");
            }
        } catch (Exception e) {
            log.error("启用分类失败", e);
            return Result.error("启用分类失败：" + e.getMessage());
        }
    }

    /**
     * 禁用分类
     */
    @PostMapping("/{categoryId}/disable")
    public Result<Void> disableCategory(@PathVariable @NotNull Long categoryId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员禁用分类: categoryId={}, operatorId={}", categoryId, operatorId);
        
        try {
            boolean success = categoryManagementService.disableCategory(categoryId, operatorId);
            if (success) {
                return Result.success("分类禁用成功");
            } else {
                return Result.error("分类禁用失败");
            }
        } catch (Exception e) {
            log.error("禁用分类失败", e);
            return Result.error("禁用分类失败：" + e.getMessage());
        }
    }

    /**
     * 更新分类排序
     */
    @PostMapping("/{categoryId}/sort")
    public Result<Void> updateCategorySortOrder(@PathVariable @NotNull Long categoryId, 
                                               @RequestParam @NotNull Integer sortOrder) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员更新分类排序: categoryId={}, sortOrder={}, operatorId={}", categoryId, sortOrder, operatorId);
        
        try {
            boolean success = categoryManagementService.updateCategorySortOrder(categoryId, sortOrder, operatorId);
            if (success) {
                return Result.success("排序更新成功");
            } else {
                return Result.error("排序更新失败");
            }
        } catch (Exception e) {
            log.error("更新分类排序失败", e);
            return Result.error("更新排序失败：" + e.getMessage());
        }
    }

    /**
     * 获取启用的分类列表（用于下拉选择）
     */
    @GetMapping("/enabled")
    public Result<List<ArticleCategory>> getEnabledCategories() {
        log.info("获取启用的分类列表");
        try {
            List<ArticleCategory> categories = categoryManagementService.getEnabledCategories();
            return Result.success(categories);
        } catch (Exception e) {
            log.error("获取启用分类列表失败", e);
            return Result.error("获取分类列表失败：" + e.getMessage());
        }
    }

    /**
     * 检查分类名称是否已存在
     */
    @GetMapping("/check-name")
    public Result<Boolean> checkCategoryName(@RequestParam String name, 
                                            @RequestParam(required = false) Long excludeId) {
        log.info("检查分类名称是否存在: name={}, excludeId={}", name, excludeId);
        try {
            boolean exists = categoryManagementService.existsCategoryName(name, excludeId);
            return Result.success(!exists); // 返回是否可用（不存在则可用）
        } catch (Exception e) {
            log.error("检查分类名称失败", e);
            return Result.error("检查分类名称失败：" + e.getMessage());
        }
    }

    /**
     * 获取分类统计信息
     */
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getCategoryStatistics() {
        log.info("获取分类统计信息");
        try {
            Map<String, Object> statistics = categoryManagementService.getCategoryStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取分类统计信息失败", e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }

    /**
     * 获取分类状态分布
     */
    @GetMapping("/status-distribution")
    public Result<List<Map<String, Object>>> getCategoryStatusDistribution() {
        log.info("获取分类状态分布");
        try {
            List<Map<String, Object>> distribution = categoryManagementService.getCategoryStatusDistribution();
            return Result.success(distribution);
        } catch (Exception e) {
            log.error("获取分类状态分布失败", e);
            return Result.error("获取状态分布失败：" + e.getMessage());
        }
    }

    /**
     * 获取分类使用情况统计
     */
    @GetMapping("/usage-statistics")
    public Result<List<Map<String, Object>>> getCategoryUsageStatistics() {
        log.info("获取分类使用情况统计");
        try {
            List<Map<String, Object>> statistics = categoryManagementService.getCategoryUsageStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取分类使用情况统计失败", e);
            return Result.error("获取使用情况统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取下一个排序值
     */
    @GetMapping("/next-sort-order")
    public Result<Integer> getNextSortOrder() {
        log.info("获取下一个排序值");
        try {
            Integer nextSortOrder = categoryManagementService.getNextSortOrder();
            return Result.success(nextSortOrder);
        } catch (Exception e) {
            log.error("获取下一个排序值失败", e);
            return Result.error("获取排序值失败：" + e.getMessage());
        }
    }
}
